package jvs.vfs.opt.media;

import java.util.ArrayList;

import jvs.vfs.FileSystem;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;

public class MediaUtils {
	private static final boolean DEBUG = FileSystem.DEBUG;
	private static final String LOG_TAG = "MediaUtils";
	
	public static final String IMAGE_SORT_BY_DATE_DESC = dateSortOrder(false);
	public static final String VIDEO_SORT_BY_DATE_DESC = dateSortOrder(false);
	public static final String AUDIO_SORT_BY_DATE_DESC = audioDateSortOrder(false);

    // The list is first sorted by date, then by id. The order can be ascending
    // or descending, depending on the mSort variable.
    // The date is obtained from the "datetaken" column. But if it is null,
    // the "date_modified" column is used instead.
    public static String dateSortOrder(boolean asc) {
        String ascending =
                (asc)
                ? " ASC"
                : " DESC";

        // Use DATE_TAKEN if it's non-null, otherwise use DATE_MODIFIED.
        // DATE_TAKEN is in milliseconds, but DATE_MODIFIED is in seconds.
        String dateExpr =
                "case ifnull(datetaken,0)" +
                " when 0 then date_modified*1000" +
                " else datetaken" +
                " end";

        // Add id to the end so that we don't ever get random sorting
        // which could happen, I suppose, if the date values are the same.
        return dateExpr + ascending + ", _id" + ascending;
    }
    
    public static String audioDateSortOrder(boolean asc) {
        String ascending =
                (asc)
                ? " ASC"
                : " DESC";
        String dateExpr =
                "case ifnull(date_added,0)" +
                " when 0 then date_modified*1000" +
                " else date_added" +
                " end";
        return dateExpr + ascending + ", _id" + ascending;
    }
    
	public static Cursor query(Context ctx, Uri uri, String[] proj, String sel,
			String[] args, String orderby) {
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, orderby);
		return c;
	}

	public static Drawable loadIcon(Context ctx, int res) {
		Bitmap b = BitmapFactory.decodeResource(ctx.getResources(), res);
		Drawable d = new BitmapDrawable(b);
		d.setFilterBitmap(false);
		d.setDither(false);
		return d;
	}

	public static void loadVideo(Context ctx, ArrayList<MediaInfo> list,
			String by, int max) {
		final String[] proj = { MediaStore.Video.Media._ID,
				MediaStore.Video.Media.DISPLAY_NAME,
				MediaStore.Video.Media.TITLE, MediaStore.Video.Media.DATA,
				MediaStore.Video.Media.SIZE,
				MediaStore.Video.Media.DATE_MODIFIED,
				MediaStore.Video.Media.DATE_TAKEN,
				MediaStore.Video.Media.MIME_TYPE,
				MediaStore.Video.Media.BUCKET_DISPLAY_NAME };

		Cursor c = query(ctx, MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
				proj, null, null, by);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			if (DEBUG) {
				Log
						.d(LOG_TAG, "loadVideoList " + c + " count: "
								+ c.getCount());
			}
			int idIdx = c.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
			int titleIdx = c
					.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE);
			int dataIdx = c.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
			int sizeIdx = c.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
			int dateIdx = c
					.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_MODIFIED);
			int typeIdx = c
					.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE);
			int bknameIdx = c
					.getColumnIndexOrThrow(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);

			long sortKey = System.currentTimeMillis();
			int count = 0;
			do {
				MediaInfo mi = new MediaInfo();
				mi.id = c.getString(idIdx);
				mi.title = c.getString(bknameIdx) + "/" + c.getString(titleIdx);
				mi.file = new java.io.File(c.getString(dataIdx));
				mi.date = c.getLong(dateIdx);
				mi.size = c.getLong(sizeIdx);
				mi.mimeType = c.getString(typeIdx);

				mi.sortkey = sortKey + "";
				sortKey++;
				//
				list.add(mi);
				//
				count++;
				if (count > max) {
					break;
				}
			} while (c.moveToNext());
			if (DEBUG) {
				Log.d(LOG_TAG, "loaded: " + list.size());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void loadImage(Context ctx, ArrayList<MediaInfo> list,
			String by, int max) {
		final String[] proj = { MediaStore.Images.Media._ID,
				MediaStore.Images.Media.DISPLAY_NAME,
				MediaStore.Images.Media.BUCKET_ID,
				MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
				MediaStore.Images.Media.DATE_MODIFIED,
				MediaStore.Images.Media.DATE_TAKEN,
				MediaStore.Images.Media.MIME_TYPE,
				MediaStore.Images.Media.SIZE, MediaStore.Images.Media.TITLE,
				MediaStore.Images.Media.DATA };

		Cursor c = query(ctx, MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				proj, null, null, by);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			if (DEBUG) {
				Log
						.d(LOG_TAG, "loadImageList " + c + " count: "
								+ c.getCount());
			}
			int idIdx = c.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
			int titleIdx = c
					.getColumnIndexOrThrow(MediaStore.Images.Media.TITLE);
			int dataIdx = c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			int sizeIdx = c.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
			int dateIdx = c
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_MODIFIED);
			int typeIdx = c
					.getColumnIndexOrThrow(MediaStore.Images.Media.MIME_TYPE);
			int bknameIdx = c
					.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);

			long sortKey = System.currentTimeMillis();
			int count = 0;
			do {
				MediaInfo mi = new MediaInfo();
				mi.id = c.getString(idIdx);
				mi.title = c.getString(bknameIdx) + "/" + c.getString(titleIdx);
				mi.file = new java.io.File(c.getString(dataIdx));
				mi.date = c.getLong(dateIdx);
				mi.size = c.getLong(sizeIdx);
				mi.mimeType = c.getString(typeIdx);
				//
				mi.sortkey = sortKey + "";
				sortKey++;
				//
				list.add(mi);
				//
				count++;
				if (count > max) {
					break;
				}
			} while (c.moveToNext());
			if (DEBUG) {
				Log.d(LOG_TAG, "loaded: " + list.size());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void loadAudio(Context ctx, ArrayList<MediaInfo> list,
			String by, int max, boolean needsIcon) {
		final String[] proj = { MediaStore.Audio.Media._ID,
				MediaStore.Audio.Media.DISPLAY_NAME,
				MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.MIME_TYPE,
				MediaStore.Audio.Media.SIZE,
				MediaStore.Audio.Media.DATE_MODIFIED,
				MediaStore.Audio.Media.DATE_ADDED,
				MediaStore.Audio.Media.ALBUM_ID, MediaStore.Audio.Media.DATA };

		Cursor c = query(ctx, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
				proj, null, null, by);
		//
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			if (DEBUG) {
				Log
						.d(LOG_TAG, "loadAudioList " + c + " count: "
								+ c.getCount());
			}
			int idIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
			int dataIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
			int dateIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATE_MODIFIED);
			int sizeIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE);
			int typeIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.MIME_TYPE);
			int aidIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID);
			int titleIdx = c.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);

			long sortKey = System.currentTimeMillis();
			int count = 0;
			do {
				MediaInfo mi = new MediaInfo();
				mi.id = c.getString(idIdx);
				mi.title = c.getString(titleIdx);
				mi.file = new java.io.File(c.getString(dataIdx));
				mi.date = c.getLong(dateIdx);
				mi.size = c.getLong(sizeIdx);
				String mt = c.getString(typeIdx);
				mi.mimeType = ((mt == null || !mt.startsWith("audio/")) ? null : mt);
				//
				// takes too long for large number of titles
				if (needsIcon) {
					int aid = c.getInt(aidIdx);
					mi.icon = ArtworkCache.getCachedArtworkIcon(ctx, aid);
				}

				mi.sortkey = sortKey + "";
				sortKey++;
				//
				list.add(mi);
				//
				count++;
				if (count > max) {
					break;
				}
			} while (c.moveToNext());
			if (DEBUG) {
				Log.d(LOG_TAG, "loaded: " + list.size());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
